#include "widget.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QNetworkConfigurationManager>

unsigned char  djbj_type;
extern QString str_mima;

const QHostAddress sendAddress = QHostAddress("230.10.10.90");
const int          sendPort    = 20090;
const QHostAddress recvAddress = QHostAddress("230.10.10.90");
const int          recvPort    = 20090;

Widget::Widget(QWidget *parent) : QWidget(parent), update_equipment_status(false), update_alarm_status(false)
{
    setFixedSize(800, 480);
    initTopLabel();
    InitStationInfo();  //初始化问题
    ReadINI();

    initUI();

    InitSpecialGBWidget();

    ////////////////////////////////////////////////////

    connect(VolumeSetUI->Cancel, SIGNAL(clicked(bool)), this, SLOT(showDefaultUI()));

    connect(&writeaudio, SIGNAL(alsaErrLog(QString)), this, SLOT(setAlsaErrRecord(QString)));

    connect(VolumeSetUI, SIGNAL(sendSetVolume(QString)), this, SLOT(setVolumeRecord(QString)));

    connect(SpecialGBUI->playstopflag, SIGNAL(clicked(bool)), this, SLOT(SetSpecialGB()));
    connect(SpecialGBUI->Cancel, SIGNAL(clicked(bool)), this, SLOT(showDefaultUI()));
    connect(SpecialGBUI->OK, SIGNAL(clicked(bool)), this, SLOT(stopGBcheck()));
    connect(SpecialGBUI, SIGNAL(specialGbUISignalforUp()), this, SLOT(specialGbUISlotforUp()));
    connect(SpecialGBUI, SIGNAL(specialGbUISignalforDown()), this, SLOT(specialGbUISlotforDown()));

    connect(EquipmentStatusUI->Cancel, SIGNAL(clicked(bool)), this, SLOT(showDefaultUI()));
    connect(EquipmentStatusUI, SIGNAL(devStateUISignalforUp()), this, SLOT(devStateUISlotforUp()));
    connect(EquipmentStatusUI, SIGNAL(devStateUISignalforDown()), this, SLOT(devStateUISlotforDown()));

    connect(loginUI, SIGNAL(pageInfo(QString)), this, SLOT(pageInfoDone(QString)));

    connect(funSelectUI, SIGNAL(pageInfo(QString)), SLOT(pageInfoDone(QString)));

    connect(selectZoneUI, SIGNAL(pageInfo(QString)), SLOT(pageInfoDone(QString)));
    connect(selectZoneUI, SIGNAL(zonePageInfo(uint8_t)), SLOT(zonePageInfoDone(uint8_t)));
    connect(selectZoneUI, SIGNAL(playCmd(QStringList, QString, QString)), SLOT(playCmdDone(QStringList, QString, QString)));
    connect(selectZoneUI, SIGNAL(monitorOpenCmd(QString, QString)), SLOT(monitorOpenCmdDone(QString, QString)));

    connect(localHostInfo, SIGNAL(pageInfo(QString)), SLOT(pageInfoDone(QString)));

    connect(settingUI, SIGNAL(pageInfo(QString)), SLOT(pageInfoDone(QString)));
    connect(settingUI, SIGNAL(emergencyInfo(int, int)), SLOT(emergencyInfo(int, int)));

    connect(http, &Http::downloadProgress, updateViewUI, &UpdateView::httpdownloadProgress);
    connect(http, &Http::downloadFileFinished, this, &Widget::httpdownloadFileFinished);

    udpSendSocket = new QUdpSocket(this);
    udpRecSocket  = new QUdpSocket(this);  // pis通用信息接收端口
    udpRecSocket->bind(recvAddress, recvPort, QUdpSocket::ShareAddress);
    if (udpRecSocket->joinMulticastGroup(recvAddress))
    {
        connect(udpRecSocket, SIGNAL(readyRead()), this, SLOT(RecvData()));
        //输出日志
        QString log = QString("DCU:%1 加入组播成功").arg(StationInfo.DCUID);
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
    else
    {
        //输出日志
        QString log = QString("DCU:%1 加入组播失败").arg(StationInfo.DCUID);
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }

    GPIOInit();

    MANGBStatus = IDLE;

    Lifetimer = new QTimer(this);
    connect(Lifetimer, SIGNAL(timeout()), this, SLOT(life_status_send()));
    Lifetimer->start(100);

    refreshViewTimer = new QTimer(this);
    connect(refreshViewTimer, SIGNAL(timeout()), this, SLOT(refreshViewTimerDown()));
    refreshViewTimer->start(300);

    Key_Init();

    SelectChannel(0);

    VolumeInit();

    writeAudioThread = new WriteAudioThread;
    writeAudioThread->setMulticastGroup(QHostAddress("230.10.10.20"), 20020);
    writeAudioThread->start();

    //输出日志
    QString log = QString("DCU:%1 系统初始化完成  软件版本 %2").arg(StationInfo.DCUID).arg(StationInfo.DCUVersion);
    writeLog(OPERATION, logLocation(LOCTION, log), true);
}

Widget::~Widget()
{
}

void Widget::msleep(int msec)
{
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while (QTime::currentTime() < dieTime) QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

void Widget::Dog_CLR(void)
{
    static unsigned char flag = 1;
    if (flag)
    {
        flag = 0;
        Dog->SetValue(H);
    }
    else
    {
        flag = 1;
        Dog->SetValue(L);
    }
}

void Widget::MAN_CLR(void)
{
    while (KeyMan->ReadValue() == L)  //人工
    {
        Dog_CLR();  //清MAX813；使MCU控制AMC有效;
        QThread::msleep(5);
        AMC->SetValue(L);
        Dog_CLR();  //清MAX813；使MCU控制AMC有效;
        QThread::msleep(5);
        AMC->SetValue(H);
        QThread::msleep(10);
    }
}

void Widget::InitSpecialGBWidget()
{
    for (int i = 0; i < maxAudioShowNum; i++)
    {
        QPushButton *Button = new QPushButton(SpecialGBUI);
        SpecialGBBtnList.append(Button);
        Button->setCheckable(true);
        Button->setText("");
        Button->setFont(QFont(ZITI, 18, QFont::Normal));
        Button->setStyleSheet(
            "QPushButton{border-image:url(:/images/ButtonPulled.png);color:rgb(19,60,76);text-align:center}"
            "QPushButton:checked{border-image:url(:/images/ButtonPushed.png);}");
        Button->setGeometry(QRect(15 + (230 + 5) * (i % 3), 30 + (60 + 5) * (i / 3), 230, 60));
        Button->hide();

        connect(Button, SIGNAL(clicked()), this, SLOT(CurrentSelectSpecialGB()));
    }
}

void Widget::CurrentSelectSpecialGB()
{
    QObject *    object = QObject::sender();
    QPushButton *Sender = qobject_cast<QPushButton *>(object);
    specialgb_id        = Sender->text().left(2).toInt();
    foreach (QPushButton *btn, SpecialGBBtnList)
    {
        if (btn->isChecked())
        {
            if (btn->text() != Sender->text())  //复位上一个选中的按钮
                btn->setChecked(false);
        }
    }
}

void Widget::SetSpecialGB()
{
    StationInfo.SpecialGB = specialgb_id;

    QString fileId = QString("%1").arg(StationInfo.SpecialGB, 2, 10, QChar('0'));

    int loopNum = StationInfo.SpecialGBLoopNumber == 0 ? 65535 : StationInfo.SpecialGBLoopNumber;

    addPacketForJson(4, StationInfo.AutoVolume, loopNum, fileId, speakerList);

    //输出日志
    QString log =
        QString("DCU:%1 开始播放特殊广播第%2条，播放%3次").arg(StationInfo.DCUID).arg(StationInfo.SpecialGB).arg(StationInfo.SpecialGBLoopNumber);

    writeLog(OPERATION, logLocation(LOCTION, log), true);
}

void Widget::showDefaultUI()
{
    StackedWidget->setCurrentIndex(1);
}

void Widget::devStateUISlotforUp()
{
    if (devStatePage > 0)
    {
        devStatePage--;
        EquipmentStatusUI->clearTabLabel();
    }
}

void Widget::devStateUISlotforDown()
{
    if (devStatePage < devStateMaxPage - 1)
    {
        devStatePage++;
        EquipmentStatusUI->clearTabLabel();
    }
}

void Widget::specialGbUISlotforUp()
{
    if (specialGbPage > 0)
    {
        specialGbPage--;
    }
}

void Widget::specialGbUISlotforDown()
{
    if (specialGbPage < specialGbMaxPage - 1)
    {
        specialGbPage++;
    }
}

void Widget::ReadINI(void)
{
    if (QFile::exists("Station.ini"))
    {
        qDebug() << "配置文件Station.ini存在，开始读取配置文件....";

        BasicIniRead = new QSettings("Station.ini", QSettings::IniFormat);
        BasicIniRead->setIniCodec(QTextCodec::codecForName("UTF-8"));
    }
    else
    {
        qDebug("Can't find Station.ini");
    }
}

void Widget::RecvData()
{
    int datasize = 0;

    QByteArray data;

    QJsonParseError error;

    datasize = udpRecSocket->pendingDatagramSize();

    data.resize(datasize);
    udpRecSocket->readDatagram(data.data(), datasize);

    QJsonDocument doc = QJsonDocument::fromJson(data, &error);
    if (error.error != QJsonParseError::NoError) return;
    // qDebug() << doc;
    if (!doc.isNull() && doc.isObject())
    {
        QJsonObject rootObj = doc.object();

        int cmdCode = rootObj["cmdCode"].toInt();

        switch (cmdCode)
        {
            case 1:
                dealCmdCode_1(rootObj);
                break;
            case 9:
                dealCmdCode_9(rootObj);
                break;
            case 11:
                dealCmdCode_11(rootObj);
                break;
            case 33:
                dealCmdCode_33(rootObj);
                break;
            case 34:
                dealCmdCode_34(rootObj);
                break;
            default:
                break;
        }
    }
    else
    {
        myCout() << "Failed to parse the Json document";
    }
}

void Widget::life_status_send()
{
    static int count = 0;
    count++;

    if (count % 10 == 1)
    {
        addPacketLifeTime();
    }
    else if (count % 10 == 2)
    {
        showDateTime();
    }
    else if (count % 10 == 3)
    {
        getNetIsOnline();
    }
    else if (count % 10 == 4)
    {
        getMapTable(devIdMap);
    }
    else if (count % 10 == 5)
    {
        addPacketForJson(8, 200, 1, "fileId", devIdList);
    }
    else if (count % 30 == 6)
    {
        m_cpuRate = getCpuUsage();
    }
    else if (count % 30 == 7)
    {
        m_memory = memoryShare();
    }
    else if (count >= 30000)
    {
        count = 0;
    }
}

void Widget::addPacketLifeTime()
{
    QJsonObject jsonObj;

    jsonObj.insert("cmdCode", 15);
    QString ip = localHostInfo->getIp();
    if (!(ip.isNull() || ip.isEmpty()))
    {
        QStringList ipList = ip.split('.');
        StationInfo.DCUID  = ipList.at(3).toInt();
    }
    jsonObj.insert("deviceId", QString::number(StationInfo.DCUID));
    jsonObj.insert("state", 1);
    jsonObj.insert("version", QString("%1.%2").arg(StationInfo.DCUVersion / 256).arg(StationInfo.DCUVersion % 256));
    jsonObj.insert("updateState", devUpdateState);
    jsonObj.insert("ip", ip);
    jsonObj.insert("deviceType", 2);
    jsonObj.insert("memory", m_memory);
    jsonObj.insert("cpu", m_cpuRate);

    QJsonDocument document;
    document.setObject(jsonObj);
    QByteArray sendBa = document.toJson(QJsonDocument::Compact);

    udpSendSocket->writeDatagram(sendBa, sendBa.size(), sendAddress, sendPort);
    QString log = QString("DCU:%1 发送生命信号").arg(StationInfo.DCUID);
    writeLog(OPERATION, logLocation(LOCTION, log));
}

void Widget::showDateTime()
{
    dateTimeText->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm"));
}

void Widget::refreshViewTimerDown()
{
    QStringList strList;

    if (devStateClear < 1)  //清除设备在线状态
    {
        foreach (QString dev, devList)
        {
            strList << dev.replace("在线", "离线");
        }
        devList = strList;
    }
    else
    {
        devStateClear--;
    }

    // qDebug() << devList << devStateClear;
    refreshView(devList, speakerList, fileNameList);
}

void Widget::Key_Init()
{
    timerkey = new QTimer(this);
    connect(timerkey, SIGNAL(timeout()), this, SLOT(keyEvent()));
    timerkey->start(100);
    QString log = QString("DCU:%1 Key_Init初始化完成").arg(StationInfo.DCUID);
    qDebug() << log;
    writeLog(OPERATION, logLocation(LOCTION, log));
}

void Widget::Key_ManGB()
{
    if (MANGBStatus == IDLE)
    {
        MANGBStatus = Com;

        addPacketForJson(2, StationInfo.ManVolume * 10, 0, "fileId", devIdList);

        if (!producer.isRunning())  //打开读线程
        {
            producer.WorkThread();
            producer.start();
            QString log = QString("DCU:%1 人工发送音频线程启动").arg(StationInfo.DCUID);
            qDebug() << log;
            writeLog(OPERATION, logLocation(LOCTION, log), true);
        }

        QString log = QString("DCU:%1 人工广播启动").arg(StationInfo.DCUID);
        qDebug() << log;
        writeLog(OPERATION, logLocation(LOCTION, log), true);

        djbj_type = RENGONG;
    }
    else if (MANGBStatus == Com)
    {
        MANGBStatus = IDLE;
        MAN_CLR();

        addPacketForJson(3, 200, 0, "fileId", devIdList);

        if (producer.isRunning())  //关闭读线程
        {
            producer.stop();
            while (producer.isRunning())
            {
                usleep(5000);
            }
            QString log = QString("DCU:%1 人工广播发送音频线程关闭").arg(StationInfo.DCUID);
            qDebug() << log;
            writeLog(OPERATION, logLocation(LOCTION, log), true);
        }

        QString log = QString("DCU:%1 人工广播关闭").arg(StationInfo.DCUID);
        qDebug() << log;
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
}

void Widget::keyEvent()
{
    static char talk_key_up  = 1;
    static char alarm_key_up = 1;
    static char man_key_up   = 1;
    static char hook_key_up  = 1;

    if (KeyTalk->ReadValue() == L && talk_key_up == 1)
    {
        talk_key_up = 0;
        NoBlockDelayms(100);
        if (KeyTalk->ReadValue() == L)
        {
            QString log = QString("DCU:%1 紧急广播按钮触发 id=%2 dev=%3").arg(StationInfo.DCUID).arg(m_emergencyIndex).arg(speakerList.join(","));
            writeLog(OPERATION, logLocation(LOCTION, log), true);

            TalkLED->SetValue(H);
            addPacketForJson(4, StationInfo.AutoVolume, 1, QString("%1").arg(m_emergencyIndex, 2, 10, QChar('0')), speakerList);
        }
    }
    else if (KeyTalk->ReadValue() == H && talk_key_up == 0)
    {
        talk_key_up = 1;
        TalkLED->SetValue(L);
    }

    if (KeyAlarm->ReadValue() == L && alarm_key_up == 1)
    {
        alarm_key_up = 0;
        NoBlockDelayms(100);
        if (KeyAlarm->ReadValue() == L)
        {
            QString log = QString("DCU:%1 应急广播按钮触发 id=%2 dev=%3").arg(StationInfo.DCUID).arg(m_crashIndex).arg(speakerList.join(","));
            writeLog(OPERATION, logLocation(LOCTION, log), true);
            AlarmLED->SetValue(H);
            addPacketForJson(4, StationInfo.AutoVolume, 1, QString("%1").arg(m_crashIndex, 2, 10, QChar('0')), speakerList);
        }
    }
    if (KeyAlarm->ReadValue() == H && alarm_key_up == 0)
    {
        alarm_key_up = 1;
        AlarmLED->SetValue(L);
    }

    static int sec = 0;
    if (KeyMan->ReadValue() == L && man_key_up == 1)
    {
        man_key_up = 0;
        if (StationInfo.CurrentGBType != OCC)
        {
            Key_ManGB();

            sec = 0;
        }
        else
        {
            MAN_CLR();
        }
    }
    if (KeyMan->ReadValue() == H && man_key_up == 0)
    {
        man_key_up = 1;
        if (MANGBStatus == Com)
        {
            Key_ManGB();
        }
    }

    if (KeyHook->ReadValue() == L && hook_key_up == 1)
    {
        hook_key_up = 0;
        NoBlockDelayms(50);
        if (KeyHook->ReadValue() == L)
        {
            QString log = QString("DCU:%1 PPT按键按下").arg(StationInfo.DCUID);
            writeLog(OPERATION, logLocation(LOCTION, log), true);
        }
    }

    if (KeyHook->ReadValue() == L) sec = 0;

    if (KeyHook->ReadValue() == H && hook_key_up == 0)
    {
        hook_key_up = 1;
        QString log = QString("DCU:%1 PPT按键抬起").arg(StationInfo.DCUID);
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }

    if (MANGBStatus == Com)
    {
        sec++;
        if (sec >= 600)  //超过两分钟自动挂断
        {
            Key_ManGB();
            QString log = QString("DCU:%1 人工广播1分钟自动挂断").arg(StationInfo.DCUID);
            writeLog(OPERATION, logLocation(LOCTION, log), true);
        }
    }
    /***************************************************************************************/
}

void Widget::writeLog(MsgType type, QString msg, bool isWrite, bool timeSync)
{
    static QStringList findRepeat;
    static QTime       last_time;
    static QString     Date = "";
    static QFile       OperationFile;
    static QStringList strList;
    static bool        timeIsTrue = false;

    if (timeSync)
    {
        timeIsTrue = true;
    }

    if (timeIsTrue == true)  //收到时间同步
    {
        if (last_time.msecsTo(QTime::currentTime()) >= 60000)
        {
            findRepeat.clear();
        }

        if (!findRepeat.contains(msg))
        {
            findRepeat.append(msg);
            isWrite = true;
        }

        if (isWrite)
        {
            QDir    dir;
            QString logPath = QString("/home/root/log/");
            QString date    = QDateTime::currentDateTime().toString("yyyy-MM-dd");
            QString text    = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + "," + msg;

            if (Date != date)
            {
                Date = date;
                if (!dir.exists(logPath))
                {
                    dir.mkdir(logPath);
                }
                logPath = logPath + "/";

                OperationFile.setFileName(QString(logPath + "DCU-%1.txt").arg(date));
                OperationFile.open(QIODevice::WriteOnly | QIODevice::Append);
            }

            if (type == OPERATION)
            {
                QTextStream out(&OperationFile);

                foreach (QString str, strList)
                {
                    out << str << "\n";
                }
                strList.clear();

                out << text << "\n";
            }
            last_time = QTime::currentTime();
        }
    }
    else
    {
        strList.append(msg);                            //时间同步之前先把日志存放到strList
        if (strList.size() >= 1000) timeIsTrue = true;  //防止一直没有校时
    }
}

/*************************************************************************************************************************
 *函数        			:   closemesbox
 *功能        			:   定时关闭提示框信息
 *参数        			:   无
 *返回        			:	无
 *依赖        			:
 *作者        			:	weikl
 *时间        			:	2019-03-24
 *最后修改时间	            :	2019-03-24
 *说明        			:
 *************************************************************************************************************************/
void Widget::closemesbox()
{
    msgBox.close();
}

void Widget::NoBlockDelayms(int ms)
{
    QTime t;
    t.start();
    while (t.elapsed() < ms) QCoreApplication::processEvents();
}

void Widget::GPIOInit(void)
{
    /*******************输出*******************/
    Beep = new GPIO(5, 4);
    Beep->Configuration(OutPut, Flip);
    Beep->SetValue(L);

    GBLED = new GPIO(5, 5);
    GBLED->Configuration(OutPut, NoFlip);
    GBLED->SetValue(L);

    COM1LED = new GPIO(5, 8);
    COM1LED->Configuration(OutPut, NoFlip);
    COM1LED->SetValue(L);

    COM2LED = new GPIO(5, 1);
    COM2LED->Configuration(OutPut, NoFlip);
    COM2LED->SetValue(L);

    TalkLED = new GPIO(5, 2);
    TalkLED->Configuration(OutPut, NoFlip);
    TalkLED->SetValue(L);

    AlarmLED = new GPIO(5, 3);
    AlarmLED->Configuration(OutPut, NoFlip);
    AlarmLED->SetValue(L);

    MasterLED = new GPIO(1, 24);
    MasterLED->Configuration(OutPut, NoFlip);
    MasterLED->SetValue(L);

    Dog = new GPIO(1, 28);
    Dog->Configuration(OutPut, NoFlip);
    Dog->SetValue(L);

    AMC = new GPIO(1, 19);
    AMC->Configuration(OutPut, NoFlip);
    AMC->SetValue(H);

    A4052 = new GPIO(4, 28);
    A4052->Configuration(OutPut, Flip);
    A4052->SetValue(H);

    B4052 = new GPIO(4, 23);
    B4052->Configuration(OutPut, Flip);
    B4052->SetValue(H);

    Mute1 = new GPIO(4, 27);
    Mute1->Configuration(OutPut, NoFlip);
    Mute1->SetValue(L);  //低电平出声

    Mute2 = new GPIO(4, 25);
    Mute2->Configuration(OutPut, NoFlip);
    Mute2->SetValue(L);  //低电平出声

    SDA3812 = new GPIO(4, 16);
    SDA3812->Configuration(OutPut, NoFlip);
    SDA3812->SetValue(L);

    SCL3812 = new GPIO(1, 1);
    SCL3812->Configuration(OutPut, NoFlip);
    SCL3812->SetValue(L);

    //    MICSelect = new GPIO(5, 6);  // H:MIC,L:声卡输出
    //    MICSelect->Configuration(OutPut, NoFlip);
    //    MICSelect->SetValue(H);
    /*******************输入*******************/
    KeyMaster = new GPIO(1, 25);
    KeyMaster->Configuration(Input, NoFlip);

    KeyTalk = new GPIO(4, 24);
    KeyTalk->Configuration(Input, NoFlip);

    KeyAlarm = new GPIO(4, 22);
    KeyAlarm->Configuration(Input, NoFlip);

    KeyMan = new GPIO(1, 29);
    KeyMan->Configuration(Input, NoFlip);

    KeyHook = new GPIO(4, 26);
    KeyHook->Configuration(Input, NoFlip);

    MAN_CLR();
}

void Widget::VolumeInit(void)
{
    SDA3812->SetValue(L);
    SCL3812->SetValue(L);
    usleep(20000);
    // BD3812初始化

    AlsaCaptureVolume("Capture", 0);                         //默认Capture Volume 0,dBscale-min=-17.25dB,step=0.75dB,min=0,max=63
    AlsaCaptureVolume("ADC PCM", 165);                       //默认ADC PCM Capture Volume 0dB,dBscale-min=-97.50dB,step=0.50dB,min=0,max=255
    AlsaCaptureVolume("Left Input Boost Mixer LINPUT1", 3);  //默认Left Input Boost Mixer LINPUT1 Volume 29dB,min=0,max=3
    AlsaCaptureVolume("ALC Max Gain", 7);                    //默认ALC Max Gain 7,min=0,max=7

    AlsaPlaybackVolume("Headphone", 121);  //默认Headphone Playback Volume 121,dBscale-min=-121.00dB,step=1.00dB,min=0,max=127,

    AlsaPlaybackVolume("Playback", 150 + 10 * StationInfo.GBJTVolume);
}

void Widget::BD3812WriteVolume(unsigned char ch1volume, unsigned char ch2volume, unsigned char adrs)
{
    unsigned char i, temp, ch1volumetemp = 0, ch2volumetemp = 0;
    if ((adrs & 0x01) == 0)  //写音量(先查表)
    {
        ch1volumetemp = ch1volume;
        ch2volumetemp = ch2volume;
    }
    else  //写增益
    {
        ch1volumetemp = ch1volume;
        ch2volumetemp = ch2volume;
    }

    temp = ch2volumetemp << 1;
    for (i = 0; i < 7; i++)
    {
        SDA3812->SetValue(L);

        usleep(10);
        SCL3812->SetValue(L);
        usleep(10);
        if (temp & 0x80)
        {
            SDA3812->SetValue(H);
        }
        else
        {
            SDA3812->SetValue(L);
        }
        usleep(10);
        SCL3812->SetValue(H);
        temp = (temp << 1);
        usleep(10);
    }

    temp = ch1volumetemp << 1;
    for (i = 0; i < 7; i++)
    {
        SDA3812->SetValue(L);
        usleep(10);
        SCL3812->SetValue(L);
        usleep(10);
        if (temp & 0x80)
        {
            SDA3812->SetValue(H);
        }
        else
        {
            SDA3812->SetValue(L);
        }
        usleep(10);
        SCL3812->SetValue(H);
        temp = (temp << 1);
        usleep(10);
    }

    temp = (adrs << 5);
    for (i = 0; i < 3; i++)
    {
        SDA3812->SetValue(L);
        usleep(10);
        SCL3812->SetValue(L);
        usleep(10);
        if (temp & 0x80)
        {
            SDA3812->SetValue(H);
        }
        else
        {
            SDA3812->SetValue(L);
        }
        usleep(10);
        SCL3812->SetValue(H);
        temp = (temp << 1);
        usleep(10);
    }

    SDA3812->SetValue(H);
    usleep(10);
    SCL3812->SetValue(L);
    usleep(10);
    SDA3812->SetValue(L);
    usleep(10);
}

void Widget::AlsaCaptureVolume(QString element, int value)
{
    long leftVal = 0, rightVal = 0;

    if (value < 0)
    {
        value = 0;
        qDebug() << "录音音量值超出范围";
    }

    snd_mixer_t *     mixer;
    snd_mixer_elem_t *pcm_element;

    int err = 0;

    if ((err = snd_mixer_open(&mixer, 0) < 0))
    {
        qDebug() << " snd_mixer_open Err \n";
        return;
    }

    snd_mixer_attach(mixer, "default");
    snd_mixer_selem_register(mixer, NULL, NULL);
    snd_mixer_load(mixer);
    pcm_element = snd_mixer_first_elem(mixer);

    while (pcm_element)
    {
        if (QString(snd_mixer_selem_get_name(pcm_element)) == element)
        {
            snd_mixer_selem_set_capture_volume_all(pcm_element, value);
            snd_mixer_selem_get_capture_volume(pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &leftVal);
            snd_mixer_selem_get_capture_volume(pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &rightVal);
            qDebug("%s NOW vol :leftVal = %ld, rightVal  = %ld", snd_mixer_selem_get_name(pcm_element), leftVal, rightVal);
            break;
        }
        else
        {
            pcm_element = snd_mixer_elem_next(pcm_element);
        }
    }
    snd_mixer_free(mixer);
}

void Widget::AlsaPlaybackVolume(QString element, int value)
{
    long leftVal = 0, rightVal = 0;
    if (value > 255)
    {
        value = 255;
        qDebug() << "播放音量值超出范围0~255";
    }
    else if (value < 0)
    {
        value = 0;
        qDebug() << "播放音量值超出范围0~255";
    }

    snd_mixer_t *     mixer;
    snd_mixer_elem_t *pcm_element;

    int err = 0;

    if ((err = snd_mixer_open(&mixer, 0) < 0))
    {
        qDebug() << " snd_mixer_open Err \n";
        return;
    }

    snd_mixer_attach(mixer, "default");
    snd_mixer_selem_register(mixer, NULL, NULL);
    snd_mixer_load(mixer);
    pcm_element = snd_mixer_first_elem(mixer);

    while (pcm_element)
    {
        if (QString(snd_mixer_selem_get_name(pcm_element)) == element)
        {
            snd_mixer_selem_set_playback_volume_all(pcm_element, value);
            snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &leftVal);
            snd_mixer_selem_get_playback_volume(pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &rightVal);
            qDebug("%s NOW vol :leftVal = %ld, rightVal  = %ld", snd_mixer_selem_get_name(pcm_element), leftVal, rightVal);
            break;
        }
        else
        {
            pcm_element = snd_mixer_elem_next(pcm_element);
        }
    }
    snd_mixer_free(mixer);
}

// 0:模拟监听；1:对讲监听；2:静音
void Widget::SelectChannel(int i)
{
    // Q_UNUSED(i);
    switch (i)
    {
        case 0:
            A4052->SetValue(H);
            B4052->SetValue(H);
            break;
        case 1:
            A4052->SetValue(H);
            B4052->SetValue(L);
            break;
        case 2:
            A4052->SetValue(L);
            B4052->SetValue(L);
            break;
        default:
            break;
    }
}

void Widget::initTopLabel()
{
    setAutoFillBackground(true);
    background = palette();
    background.setBrush(QPalette::Window, QBrush(QPixmap(":/images/background.png")));
    setPalette(background);

    netModeText = new QLabel(this);
    netModeText->setText(tr("网络"));
    netModeText->setFont(QFont(ZITI, 15, QFont::Bold));
    netModeText->setGeometry(QRect(15, 5, 45, 49));
    netModeText->setStyleSheet("color:white");

    netModeImage = new QLabel(this);
    netModeImage->setText(tr(""));
    netModeImage->setFont(QFont(ZITI, 12, QFont::Bold));
    netModeImage->setGeometry(QRect(60, 2, 40, 49));
    netModeImage->setStyleSheet("color:white;border-image:url(:/images/offline.png)");

    LineNameL = new QLabel(this);
    LineNameL->setText(tr("站台控制终端"));
    LineNameL->setFont(QFont(ZITI, 24, QFont::Normal));
    LineNameL->setGeometry(QRect(300, 12, 200, 31));
    LineNameL->setStyleSheet("color:white;text-align:center");

    dateTimeText = new QLabel(this);
    dateTimeText->setText(tr("2024-09-22 20:50"));
    dateTimeText->setFont(QFont(ZITI, 15, QFont::Bold));
    dateTimeText->setGeometry(QRect(600, 2, 200, 49));
    dateTimeText->setStyleSheet("color:white");
}

void Widget::initUI()
{
    loginUI           = new LoginUI;
    funSelectUI       = new FunSelectUI;
    VolumeSetUI       = new VolumeSet;
    SpecialGBUI       = new SpecialGB;
    EquipmentStatusUI = new EquipmentStatus;
    selectZoneUI      = new SelectZoneUI;
    localHostInfo     = new LocalHostInfo;
    settingUI         = new Setting;
    updateViewUI      = new UpdateView;
    http              = new Http;

    StackedWidget = new QStackedWidget(this);
    StackedWidget->setGeometry(QRect(0, 50, 795, 422));
    StackedWidget->addWidget(loginUI);            // 0
    StackedWidget->addWidget(funSelectUI);        // 1
    StackedWidget->addWidget(VolumeSetUI);        // 2
    StackedWidget->addWidget(SpecialGBUI);        // 3
    StackedWidget->addWidget(EquipmentStatusUI);  // 4
    StackedWidget->addWidget(selectZoneUI);       // 5
    StackedWidget->addWidget(localHostInfo);      // 6
    StackedWidget->addWidget(settingUI);          // 7
    StackedWidget->addWidget(updateViewUI);       // 8
}

void Widget::setAlsaErrRecord(QString errInfo)
{
    //输出日志
    QString log = QString("DCU:%1 ").arg(StationInfo.DCUID) + errInfo;
    qDebug() << log;
    writeLog(OPERATION, logLocation(LOCTION, log), true);
}

void Widget::setVolumeRecord(QString operation)
{
    AlsaPlaybackVolume("Playback", 150 + 10 * StationInfo.GBJTVolume);
    setVolumeByJson();
    //输出日志
    QString log = QString("DCU:%1 ").arg(StationInfo.DCUID) + operation;
    qDebug() << log;
    writeLog(OPERATION, logLocation(LOCTION, log), true);
}

QString Widget::logLocation(QString loc, QString msg)
{
    return loc.replace("\\", "/").append(msg);
}

void Widget::syncDateTime(QString dateTime)
{
    QString cmd;

    QDateTime time1  = QDateTime::fromString(dateTime, "yyyy-MM-dd HH:mm:ss");
    QDateTime time2  = QDateTime::currentDateTime();
    int       second = qAbs(time1.secsTo(time2));

    if (second >= 3)
    {
        cmd = QString("date -s '%1'").arg(dateTime);
        system(cmd.toUtf8().data());
        writeLog(OPERATION, logLocation(LOCTION, QString("收到主机时间同步：%1").arg(time1.toString("yyyy-MM-dd HH:mm:ss"))), true, true);
    }
}

QString Widget::getDevName(int type)
{
    QString devName = "";

    switch (type)
    {
        case 1:
            devName = QString("主机");
            break;
        case 2:
            devName = QString("呼叫站");
            break;
        case 3:
            devName = QString("扬声器");
            break;
        default:
            devName = QString("未知");
            break;
    }
    return devName;
}

void Widget::getNetIsOnline()
{
    QNetworkConfigurationManager manager;
    QList<QNetworkConfiguration> configuration = manager.allConfigurations();

    foreach (const QNetworkConfiguration &config, configuration)
    {
        if (config.name() == "eth0")
        {
            if (manager.isOnline())
            {
                netModeImage->setStyleSheet("color:white;border-image:url(:/images/online.png)");
            }
            else
            {
                netModeImage->setStyleSheet("color:white;border-image:url(:/images/offline.png)");
            }
        }
    }
}

void Widget::addGroupByFindDev(QMap<int, QString> groupMap, QStringList &devList, QList<int> list)
{
    foreach (QString devInfo, devList)
    {
        foreach (int devId, list)
        {
            if (devInfo.contains(QString("扬声器%1").arg(devId)))
            {
                int index = devList.indexOf(devInfo);
                devInfo.replace("*", groupMap.value(devId));
                devList.replace(index, devInfo);
            }
        }
    }
}

void Widget::pageInfoDone(QString info)
{
    if (info == "登陆成功" || info == "返回")
    {
        StackedWidget->setCurrentIndex(1);
    }
    else if (info == "音量设置")
    {
        StackedWidget->setCurrentIndex(2);
    }
    else if (info == "特殊广播")
    {
        foreach (QPushButton *btn, SpecialGBBtnList)  //清除所有按钮打选中状态
        {
            if (btn->isChecked())
            {
                btn->setChecked(false);
            }
        }
        StationInfo.SpecialGBLoopNumber = 0;
        StationInfo.SpecialGB = specialgb_id = 1;
        // SpecialGBUI->LoopNumber->setText(QString("%1").arg(StationInfo.SpecialGBLoopNumber));
        SpecialGBUI->LoopNumber->setText("∞");
        StackedWidget->setCurrentIndex(3);
    }
    else if (info == "设备状态")
    {
        StackedWidget->setCurrentIndex(4);
    }
    else if (info == "分区")
    {
        StackedWidget->setCurrentIndex(5);
    }
    else if (info == "本机信息")
    {
        StackedWidget->setCurrentIndex(6);
    }
    else if (info == "设置")
    {
        StackedWidget->setCurrentIndex(7);
    }
    else if (info == "退出")
    {
        StackedWidget->setCurrentIndex(0);
    }
}

void Widget::emergencyInfo(int emergencyIndex, int crashIndex)
{
    m_emergencyIndex = emergencyIndex + 1;
    m_crashIndex     = crashIndex + 1;
}

void Widget::zonePageInfoDone(uint8_t page)
{
    zonePage = page;
}

void Widget::playCmdDone(QStringList speakerIdList, QString cmd, QString fileId)
{
    if (cmd == "play")
    {
        addPacketForJson(4, StationInfo.AutoVolume, 1, fileId, speakerIdList);

        QString log = QString("DCU:%1 选中扬声器播放 fileId=%2 dev=%3").arg(StationInfo.DCUID).arg(fileId).arg(speakerIdList.join(","));
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
    else if (cmd == "stop")
    {
        addPacketForJson(5, StationInfo.AutoVolume, 1, fileId, speakerIdList);

        QString log = QString("DCU:%1 选中扬声器停止 fileId=%2 dev=%3").arg(StationInfo.DCUID).arg(fileId).arg(speakerIdList.join(","));
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
}

void Widget::monitorOpenCmdDone(QString groupId, QString cmd)
{
    uint8_t ip = 0;

    if ((groupId.toInt() - 1) < speakerList.size())  //选中监听的扬声器必须在列表之内
    {
        ip = speakerList.at(groupId.toInt() - 1).toInt();
    }

    if (cmd == "play")
    {
        writeAudioThread->setProcessFlag(true);
        writeAudioThread->filterAudio(ip);

        QString log = QString("DCU:%1 监听打开 index=%2 dev=%3").arg(StationInfo.DCUID).arg(groupId.toInt()).arg(ip);
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
    else if (cmd == "stop")
    {
        writeAudioThread->setProcessFlag(false);
        writeAudioThread->filterAudio(ip);

        QString log = QString("DCU:%1 监听关闭 index=%2 dev=%3").arg(StationInfo.DCUID).arg(groupId.toInt()).arg(ip);
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
    else if (cmd == "selfPlay")
    {
        QStringList devList;
        devList << QString::number(StationInfo.DCUID);
        writeAudioThread->setProcessFlag(true);
        writeAudioThread->filterAudio(StationInfo.DCUID);
        addPacketForJson(4, StationInfo.AutoVolume, 1, selectZoneUI->getFileId(), devList);
        QString log = QString("DCU:%1 试听播放 id=%2 dev=%3").arg(StationInfo.DCUID).arg(selectZoneUI->getFileId()).arg(devList.join(""));
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
    else if (cmd == "selfStop")
    {
        QStringList devList;
        devList << QString::number(StationInfo.DCUID);
        writeAudioThread->setProcessFlag(false);
        writeAudioThread->filterAudio(0);
        addPacketForJson(5, StationInfo.AutoVolume, 1, selectZoneUI->getFileId(), devList);
        QString log = QString("DCU:%1 试听取消").arg(StationInfo.DCUID);
        writeLog(OPERATION, logLocation(LOCTION, log), true);
    }
}

void Widget::addPacketForJson(int cmdCode, int volume, int count, QString fileId, QStringList deviceList)
{
    QJsonObject sendObject;
    QJsonArray  devJsonArray;
    QJsonArray  mapJsonArray;

    sendObject["cmdCode"] = cmdCode;
    sendObject["volume"]  = volume;
    sendObject["count"]   = count;
    sendObject["fileId"]  = fileId;

    foreach (QString var, deviceList)
    {
        devJsonArray.append(QJsonValue(var));
    }
    sendObject["deviceList"] = devJsonArray;

    QMapIterator<QString, QString> itor(devIdMap);
    while (itor.hasNext())
    {
        itor.next();
        QJsonObject obj;
        obj[itor.key()] = itor.value();
        mapJsonArray.append(obj);
    }

    sendObject["devIdMap"] = mapJsonArray;

    QJsonDocument document;
    document.setObject(sendObject);
    QByteArray sendBa = document.toJson(QJsonDocument::Compact);

    udpSendSocket->writeDatagram(sendBa, sendBa.size(), sendAddress, sendPort);
}

void Widget::stopGBcheck()
{
    QString fileId = QString::number(StationInfo.SpecialGB);

    addPacketForJson(5, StationInfo.AutoVolume, StationInfo.SpecialGBLoopNumber, fileId, speakerList);
    QString log = QString("DCU:%1 停止播放特殊广播").arg(StationInfo.DCUID);
    writeLog(OPERATION, logLocation(LOCTION, log), true);
}

void Widget::httpdownloadFileFinished()
{
    devUpdateState = 2;
    updateViewUI->outPutLog("下载完成");
    if (md5Sum == readFileMd5(UPDATEPATH))
    {
        updateViewUI->outPutLog("md5校验通过");

        msleep(5000);
        system("/opt/finish.sh");
    }
    else
    {
        updateViewUI->outPutLog("md5校验不通过");
    }
}

void Widget::refreshView(QStringList devList, QStringList speakerList, QStringList fileNames)
{
    static QStringList     tempDevList;
    static QStringList     tempGroupIdList;
    static QStringList     tempfileNameList;
    static uint8_t         tempZonePage;
    static uint8_t         tempDevStatePage;
    static uint8_t         tempFileNamePage;
    QMap<QString, QString> tempDevIdMap;

    if (tempGroupIdList != speakerList || tempZonePage != zonePage || tempDevIdMap != devIdMap)
    {
        tempGroupIdList = speakerList;
        tempZonePage    = zonePage;
        tempDevIdMap != devIdMap;
        selectZoneUI->setSelectGroupLabel(speakerList, devIdMap, zonePage);
    }

    if (tempDevList != devList || tempDevStatePage != devStatePage)
    {
        tempDevList      = devList;
        tempDevStatePage = devStatePage;
        EquipmentStatusUI->clearTabLabel();
        EquipmentStatusUI->setTabLabel(devList, devStatePage);
    }

    if (tempfileNameList != fileNames || tempFileNamePage != specialGbPage)
    {
        tempfileNameList = fileNames;
        tempFileNamePage = specialGbPage;

        setAudioList(fileNames, specialGbPage);

        settingUI->setAudioList(fileNames);
    }
}

void Widget::getMapTable(QMap<QString, QString> &map)
{
    if (map.isEmpty())
    {
        QFile file("./devIdMap.json");
        if (file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QByteArray data = file.readAll();
            file.close();
            QJsonDocument doc = QJsonDocument::fromJson(data);
            QJsonObject   obj = doc.object();

            QJsonArray arry = obj["devIdMap"].toArray();

            for (int var = 0; var < arry.size(); ++var)
            {
                QJsonValue  jsonValue = arry.at(var);
                QJsonObject jsonObj   = jsonValue.toObject();
                QString     key       = jsonObj.keys().at(0);
                QString     value     = jsonObj.value(key).toString();

                map.insert(key, value);
            }
        }
    }
}

void Widget::dealCmdCode_1(QJsonObject rootObj)
{
    devList.clear();
    devIdList.clear();
    speakerList.clear();
    // qDebug() << rootObj;
    QJsonArray devInfoArray = rootObj["statusList"].toArray();
    COM1LED->SetValue(ValueType(H ^ COM1LED->ReadValue()));
    foreach (QJsonValue val, devInfoArray)  //遍历获取设备信息
    {
        QJsonObject obj = val.toObject();

        int dbState = obj["dbState"].toInt();

        QString devIdInner = obj["deviceId"].toString();
        QString type       = obj["type"].toString();
        QString devName    = getDevName(type.toInt());
        QString devIdOut   = devIdMap.value(devIdInner);
        int     state      = obj["state"].toInt();
        QString ip         = obj["ip"].toString();
        int     vol        = obj["volume"].toInt();
        QString ver        = obj["version"].toString();

        QString strState;

        switch (state)
        {
            case 1:
                strState = "在线";
                break;
            case 2:
                strState = "离线";
                break;
            case 3:
                strState = "占用";
                break;
            default:
                strState = QString("errCode%1").arg(state);
                break;
        }

        QString dev = QString("%1#%2#%3#%4#%5#%6#%7").arg(devIdOut).arg(dbState).arg(devName).arg(ip).arg(vol).arg(ver).arg(strState);

        if (!devList.contains(dev))  // 保存设备列表以便显示
        {
            devList.append(dev);
        }

        if (!devIdList.contains(devIdInner))
        {
            devIdList.append(devIdInner);
        }

        if (type == "3" && !speakerList.contains(devIdInner))
        {
            speakerList.append(devIdInner);
        }
    }

    if (devList.size() % 9 == 0)
    {
        devStateMaxPage = devList.size() / 9;
    }
    else
    {
        devStateMaxPage = devList.size() / 9 + 1;
    }

    QString time = rootObj["time"].toString();

    syncDateTime(time);

    devStateClear = 10;  //收不到网关发出来的状态信心，10s后自动离线
}

void Widget::dealCmdCode_9(QJsonObject rootObj)
{
    QJsonArray devInfoArray = rootObj["fileList"].toArray();

    QStringList fileNames;

    foreach (QJsonValue val, devInfoArray)  //遍历获取设备信息
    {
        QJsonObject obj      = val.toObject();
        QString     fileName = obj["fileName"].toString();
        if (!fileName.isNull() && !fileName.isEmpty())
        {
            fileNames.append(fileName.split('.').at(0));  //去除媒体文件后缀
        }
    }

    qSort(fileNames);

    fileNameList = fileNames;

    if (fileNameList.size() % 9 == 0)
    {
        specialGbMaxPage = fileNameList.size() / maxAudioShowNum;
    }
    else
    {
        specialGbMaxPage = fileNameList.size() / maxAudioShowNum + 1;
    }
}

void Widget::dealCmdCode_11(QJsonObject rootObj)
{
    int        cmdType   = rootObj["cmdType"].toInt();
    QJsonArray jsonArray = rootObj["deviceList"].toArray();

    if (cmdType == 11)
    {
        QJsonValue devIp = QJsonValue(QString::number(StationInfo.DCUID));
        if (jsonArray.contains(devIp))
        {
            msgBoxShow("收到重启指令");

            QTimer::singleShot(3000, this, [=]() {
                QProcess process;
                msgBoxClose();
                process.start("reboot");
                process.waitForFinished();
            });
        }
    }
}

void Widget::dealCmdCode_33(QJsonObject rootObj)
{
    qDebug() << rootObj;
    QString url          = rootObj["fileUrl"].toString();
    md5Sum               = rootObj["md5"].toString();
    QJsonArray jsonArray = rootObj["deviceList"].toArray();
    QJsonValue devIp     = QJsonValue(QString::number(StationInfo.DCUID));
    if (jsonArray.contains(devIp))
    {
        updateViewUI->clearLog();
        msgBoxShow("收到升级指令");
        updateViewUI->outPutLog("收到升级指令");
        devUpdateState = 1;
        QTimer::singleShot(3000, this, [=]() {
            msgBoxClose();
            updateViewUI->outPutLog(QString("收到URL：%1").arg(url));
            http->startRequst(QUrl(url));
            StackedWidget->setCurrentIndex(8);
        });
    }
}

void Widget::dealCmdCode_34(QJsonObject rootObj)
{
    // qDebug() << rootObj;
    static QList<int> tempList;
    QList<int>        volList;

    int8_t ttsVol     = rootObj["volume"].toString().toInt();
    int8_t ttsSpeed   = rootObj["speed"].toString().toInt();
    int8_t ttsTimbre  = rootObj["timbre"].toString().toInt();
    int8_t manVol     = rootObj["manVol"].toString().toInt();
    int8_t monitorVol = rootObj["monitorVol"].toString().toInt();

    volList.append(ttsVol);
    volList.append(ttsSpeed);
    volList.append(ttsTimbre);
    volList.append(manVol);
    volList.append(monitorVol);

    if (tempList != volList)
    {
        tempList = volList;

        VolumeSetUI->syncVolume(volList);
        QJsonDocument doc;
        doc.setObject(rootObj);
        QString log = QString("DCU:%1 ").arg(StationInfo.DCUID) + doc.toJson(QJsonDocument::Compact);
        writeLog(OPERATION, logLocation(LOCTION, log), false);
    }
}

void Widget::msgBoxShow(QString msg)
{
    if (!msgBox.isVisible())
    {
        msgBox.setText(msg);
        msgBox.setFont(QFont(ZITI, 20, QFont::Bold));
        msgBox.setStyleSheet("color:red;text-align:center;");
        msgBox.show();
    }
}

void Widget::msgBoxClose()
{
    if (msgBox.isVisible())
    {
        msgBox.close();
    }
}

void Widget::setAudioList(QStringList fileNameList, int page)
{
    for (int i = 0; i < maxAudioShowNum; i++)
    {
        int index = i + page * 15;
        if (index < fileNameList.size())  //更新呼叫站预录播放列表
        {
            SpecialGBBtnList.at(i)->show();
            SpecialGBBtnList.at(i)->setText(fileNameList.at(index));
        }
        else
        {
            SpecialGBBtnList.at(i)->hide();  //隐藏多余按钮
        }
    }
}

QString Widget::readFileMd5(QString filePath)
{
    QByteArray         md5;
    QFile              file(filePath);
    QCryptographicHash hash(QCryptographicHash::Md5);

    if (file.open(QIODevice::ReadOnly))  //打开文件
    {
        while (!file.atEnd())
        {
            QByteArray content = file.read(1024 * 1024 * 100);
            hash.addData(content);
        }
        md5 = hash.result();
        //打印MD5码
        qDebug() << "MD5:" << md5.toHex();
        file.close();
    }
    else
    {
        qDebug() << "打开文件失败";
    }
    return md5.toHex();
}

int8_t Widget::getCpuUsage()
{
    QProcess process;
    process.start("cat /proc/stat");
    process.waitForFinished();
    QString str = process.readLine();
    str.replace("\n", "");
    str.replace(QRegExp("( ){1,}"), " ");
    auto lst = str.split(" ");
    if (lst.size() > 3)
    {
        double use   = lst[1].toDouble() + lst[2].toDouble() + lst[3].toDouble();
        double total = 0;
        for (int i = 1; i < lst.size(); ++i) total += lst[i].toDouble();
        if (total - m_cpu_total__ > 0)
        {
            double cpuRate = (use - m_cpu_use__) / (total - m_cpu_total__) * 100.0;
            // qDebug("cpu rate:%.2lf%%", cpuRate);
            m_cpu_total__ = total;
            m_cpu_use__   = use;
            return cpuRate;
        }
    }
    return 0;
}

int8_t Widget::memoryShare()
{
    QProcess process;
    process.start("free -m");  //使用free完成获取
    process.waitForFinished();
    process.readLine();
    QString str = process.readLine();
    str.replace("\n", "");
    str.replace(QRegExp("( ){1,}"), " ");  //将连续空格替换为单个空格 用于分割
    auto   lst = str.split(" ");
    int8_t percentage;

    if (lst.size() > 6)
    {
        double space_all       = lst[1].toDouble();
        double space_available = lst[3].toDouble();

        percentage = (space_all - space_available) * 100 / space_all;
    }
    return percentage;
}

void Widget::setVolumeByJson()
{
    QJsonObject jsonObj;
    jsonObj.insert("cmdCode", 14);
    jsonObj.insert("manVol", StationInfo.ManVolume);
    jsonObj.insert("monitorVol", StationInfo.GBJTVolume);
    QJsonDocument document;
    document.setObject(jsonObj);
    QByteArray sendBa = document.toJson(QJsonDocument::Compact);

    udpSendSocket->writeDatagram(sendBa, sendBa.size(), sendAddress, sendPort);
}
